package com.asurplus.common.realname.api;

import com.asurplus.common.realname.util.AESUtil;
import com.asurplus.common.realname.util.ParamSecretUtil;
import org.nutz.http.Header;
import org.nutz.http.Request;
import org.nutz.http.Request.METHOD;
import org.nutz.http.Sender;
import org.nutz.http.sender.GetSender;
import org.nutz.http.sender.PostSender;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;

import java.util.HashMap;
import java.util.Map;

/**
 * 请求接口包装类，这里需要考虑多线程问题，发送时需新建一个sender
 *
 * @author lizhou
 */
public class RequestBuilder {

    /**
     * 请求地址
     */
    private String url;
    /**
     * 请求方式
     */
    private METHOD method;
    /**
     * 接口调用唯一凭证
     */
    private String appId;
    /**
     * 业务权限标识
     */
    private String bizId;
    /**
     * 访问密钥
     */
    private String secretKey;

    public RequestBuilder(String url, METHOD method, String appId, String bizId, String secretKey) {
        this.url = url;
        this.method = method;
        this.appId = appId;
        this.bizId = bizId;
        this.secretKey = secretKey;
    }

    /**
     * 新建发送对像
     *
     * @param bodyParameters body参数
     * @param extParams      部分接口需要明参
     * @return
     */
    public Sender build(Map<String, Object> bodyParameters, String... extParams) {
        final Map<String, String> headerParameters = new HashMap<String, String>();
        headerParameters.put("Content-Type", "application/json;charset=utf-8");
        headerParameters.put("appId", appId);
        headerParameters.put("bizId", bizId);

        //部分请求需要带明参
        String url = this.url;
        Map<String, Object> extParamsMap = new HashMap<>();
        StringBuilder urlB = new StringBuilder();
        urlB.append(this.url).append("?");
        if (extParams != null && extParams.length > 0) {
            for (int i = 0; i < extParams.length; i += 2) {
                String k = extParams[i];
                String v = extParams[i + 1];
                urlB.append(k).append("=").append(v).append("&");

                extParamsMap.put(k, v);//签名需要
            }
            urlB.setLength(urlB.length() - 1);//最一个&不要
            url = urlB.toString();
        }
        Request request = Request.create(url, method);
        headerParameters.put("timestamps", String.valueOf(System.currentTimeMillis()));

        String sign = ParamSecretUtil.buildSign(headerParameters, extParamsMap, secretKey);
        Header header = Header.create(headerParameters);
        header.set("sign", sign);
        request.setHeader(header);

        Sender sender;
        if (this.method == METHOD.POST) {
            sender = new PostSender(request);
        } else {
            sender = new GetSender(request);
        }
        return sender;
    }

    public Sender build(Map<String, Object> bodyParameters) {
        final Map<String, String> headerParameters = new HashMap<String, String>();
        headerParameters.put("Content-Type", "application/json;charset=utf-8");
        headerParameters.put("appId", appId);
        headerParameters.put("bizId", bizId);

        Request request = Request.create(url, method);
        headerParameters.put("timestamps", String.valueOf(System.currentTimeMillis()));
        //body参数加密并包装下
        String body = Json.toJson(bodyParameters, JsonFormat.compact());
        String bodyEncode = AESUtil.Encrypt(body, secretKey);
        StringBuilder bodyBuilder = new StringBuilder();
        bodyBuilder.append("{\"data\":\"").append(bodyEncode).append("\"}");
        String bodyData = bodyBuilder.toString();

        String sign = ParamSecretUtil.buildSign(headerParameters, bodyData, secretKey);
        Header header = Header.create(headerParameters);
        header.set("sign", sign);
        request.setHeader(header);

        Sender sender;
        if (this.method == METHOD.POST) {
            request.setData(bodyData);
            sender = new PostSender(request);
        } else {
            sender = new GetSender(request);
        }
        return sender;
    }
}
